/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 2012  Роман Браун <firdragon76@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "sudokuitem.h"
#include <QtCore/qmath.h>

SudokuItem::SudokuItem(QObject *parent): QObject(parent), statValue(0), status(SS::EMPTY)
{
	candidats.resize(SS::TABLE_SIZE);
}

SudokuItem::SudokuItem(const SudokuItem &si): QObject(si.parent())
{
	statValue = si.statValue;
	status = si.status;
	candidats = si.candidats;
}

SudokuItem::~SudokuItem()
{

}

void SudokuItem::addCanditat(const quint16 &pos, const quint16 &val)
{
	Q_ASSERT(pos < candidats.count());

	if(candidats.at(pos) == 0)
	{
		candidats[pos] = val;
		status = SS::CANDIDATS;
	}

	else
	{
		candidats[pos] = 0;

		if(isEmpty())
			status = SS::EMPTY;
	}

}

QVector< quint16 > SudokuItem::getCandidats() const
{
	return candidats;
}

SS::ITEM_STATUS SudokuItem::getStatus() const
{
	return status;
}

quint16 SudokuItem::getValue() const
{
	return statValue;
}

quint16 SudokuItem::getViewValue() const
{
	if(status == SS::STATIC)
		return statValue;

	if(status == SS::CANDIDATS && isOneCandidat())
		return oneCandidat();

	else
		return 0;
}

bool SudokuItem::isOneCandidat() const
{
	quint16 i, c = 0;

	foreach(i, candidats)
	{
		if(i != 0)
			c++;
	}

	if(c == 1)
		return true;

	return false;
}

quint16 SudokuItem::oneCandidat() const
{
	quint16 i;

	foreach(i, candidats)
	{
		if(i != 0)
			return i;
	}

	return 0;
}

void SudokuItem::setStatus(SS::ITEM_STATUS status)
{
	this->status = status;
}

void SudokuItem::setValue(const quint16 &value)
{
	statValue = value;
}

SudokuItem &SudokuItem::operator=(const SudokuItem &si)
{
	setParent(si.parent());
	statValue = si.statValue;
	status = si.status;
	candidats = si.candidats;
	return *this;
}

QString SudokuItem::getCandidatsString() const
{
	QString ret = QString();
	quint32 n = qSqrt(SS::TABLE_SIZE);

	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
		{
			QString e;

			if(candidats.at(i * n + j) == 0)
				e = " ";

			else
				e.setNum(candidats.at(i * n + j));

			ret += e + " ";
		}

		ret += "\n";
	}

	ret.remove(ret.count() - 1, 1);
	return ret;
}

bool SudokuItem::isEmpty() const
{
	if(status == SS::STATIC)
		return false;

	quint32 n = 0;
	quint16 i;

	foreach(i, candidats)
	{
		n += i;
	}

	if(n == 0)
		return true;

	else
		return false;
}

#include "sudokuitem.moc"
